package AI;

import java.util.Iterator;
import java.util.Vector;
import orfeu.engine.*;
import android.util.Log;

public class Hell implements Runnable{
	
	static public int HEALTH = 100; //Health
	static public float SPEED = 0.3f; //Speed
	static public float P_SPEED = 0.1f;
	static public int ATTACK = HEALTH/4; //Attack
	static public Vector<Demon> demons ;
	static public int DEMONS_NUMBER = 5;
	static public int TIME_FOR_NEXT_WAVE = 3000;
	static public Vector<Projectile> enemyProjectiles;
	static public Vector<Projectile> myProjectiles ;
	static public AudioClip myaudioclip;
	
	//Keep a static reference to some demons in order to get their loaded texture Id's
	public static Sprite dummyFlyer;
	public static Sprite dummyExploder;
	public static Sprite dummyCrawler;
	public static Projectile firstProjectile;
	public static Sprite dummyExplode;
	private boolean running;
	
	
	//We have no use for these variables, but i don't want to mess with the code
	private GLRenderer renderer;
	private GameUpdater updater;
	
	boolean flag = false;
	
	public Hell() {
		this.renderer = GLView.getRenderer();
		this.updater = GLView.getUpdater();
		myaudioclip=new AudioClip(SpriteGameActivity.context, R.raw.explosion);
		enemyProjectiles = new Vector<Projectile>();
		myProjectiles = new Vector<Projectile>();
		demons = new Vector<Demon>();
		this.setRunning(true);
	}
	
	public void setRunning(boolean value) {
		this.running = value;
	}
	
	public void run() {
		while (running)
			GLView.getGenerator().generateWave();
	}
	
	public void generateWave() {

		//Updateaza highscore global si reseteaza scorul local
		Hero.getHero().HIGHSCORE += Hero.getHero().SCORE;
		Hero.getHero().SCORE = 0;

		for (int i = 0; i < Hell.DEMONS_NUMBER; i++) {
			Demon d = new Demon(64, 64, 4, 100, R.drawable.flyer);
			if(d.flyer) d.textureId = Hell.dummyFlyer.textureId;
			else if(d.crawler) d.textureId = Hell.dummyCrawler.textureId;
			else if(d.exploder) d.textureId = Hell.dummyExploder.textureId;
			
			
			//TODO: load texture
			synchronized(renderer.drawList) {
				d.myaudioclip=myaudioclip;
				renderer.drawList.add(d);
				renderer.drawList.notifyAll();
			}
			synchronized(updater.updateList) {
				updater.updateList.add(d);
				updater.updateList.notifyAll();
			}
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

		try {
			Thread.sleep(Hell.TIME_FOR_NEXT_WAVE * Hell.DEMONS_NUMBER);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		//Update for the next wave
		Hell.DEMONS_NUMBER += 2;
		Hell.HEALTH += 20;
		Hell.SPEED += 0.05f;
		Hell.ATTACK += 10;
		
		//TODO: creste viata eroului, upgrade hero in general
		Hero.getHero().MAX_HEALTH += 200f;
		Hero.getHero().HEALTH = Math.min(Hero.getHero().MAX_HEALTH, 
										Hero.getHero().HEALTH + Hero.getHero().SCORE/2); //ii creste viata
		//if(Hero.getHero().HEALTH > Constants.MAX_HERO_HEALTH) Hero.getHero().HEALTH = Constants.MAX_HERO_HEALTH;
		Hero.getHero().proj_rate += 100;
		Hero.getHero().damage += 20;
		//Log.d("i", "S-a updatat viata eroului: " + Hero.getHero().HEALTH);
		
	}
	
	public  synchronized void detectProjectilesCollsion(){
		synchronized(enemyProjectiles){
			Iterator<Projectile> itenemy = enemyProjectiles.iterator();
			while(itenemy.hasNext()) {
				Projectile p = itenemy.next();
				synchronized(myProjectiles)
				{
					Iterator<Projectile> ithero = myProjectiles.iterator();
					while(ithero.hasNext()) {
						Projectile heroone = ithero.next();
						if (p.collidesWith(heroone)) {

						//Tell the sprite that it doesn't have to be drawn anymore
						p.setRemove();
						heroone.setRemove();
							//TODO: animatie pt proiectile care se intersecteaza
							ithero.remove(); //se scot proiectilele din liste
							itenemy.remove(); 
						}
					}
					myProjectiles.notifyAll();
				}
			}
			enemyProjectiles.notifyAll();
		}
	}
	
	public void damageDemons(){
		
		synchronized (myProjectiles) {
			Iterator<Projectile> it = myProjectiles.iterator();
			
			while(it.hasNext()) {
				Projectile p = it.next();
				
				synchronized(demons) {
					Iterator<Demon> itDemons = demons.iterator();
					while(itDemons.hasNext()) {
						Demon d = itDemons.next();
						if (p.collidesWith(d)) {
							Hell.myaudioclip.play();
							Hero.getHero().SCORE += Math.min(p.damage, d.health);
							//Log.d("i", "Rage inainte = " + Hero.getHero().getRage());
							//Log.d("i", "p.damage = " + p.damage + ", d.health = " + d.health);
							float rage = Hero.getHero().getRage() + 3f * Math.min(p.damage, d.health);
							rage = Math.min(rage, Hero.getHero().MAX_HEALTH);
							Hero.getHero().setRage(rage);
							//Log.d("i", "Rage dupa = " + Hero.getHero().getRage());
							d.updateHealth(p.damage);
							boolean demonMort = !d.isAlive();
							
							//Tell the sprite that it has to be removed
							p.setRemove();
							
							if (demonMort){
								itDemons.remove();
								d.setRemove();
							}
							it.remove(); //se scoate proiectilul din lista
						}
					}
					demons.notifyAll();	
				}
			}
			myProjectiles.notifyAll();
		}
	}
	//metoda care verifica daca proiectilele demonilor ating eroul
	//si ii iau din viata
	public void damageHero() throws DeathException{
		
		synchronized (Hero.getHero()){
			Hero h = Hero.getHero();
			
			synchronized (enemyProjectiles){
				Iterator<Projectile> itenemy = enemyProjectiles.iterator();
				
				while(itenemy.hasNext()) {
					Projectile p = itenemy.next();
					
					if (h.collidesWith(p)) {
						Hell.myaudioclip.play();
						h.updateHealth(p.damage);
						
						//tell the sprite that is has to be removed
						p.setRemove();
						itenemy.remove();
						if (!h.isAlive()){ //eroul a murit
							//TODO: ce se intampla cand eroul moare	
							throw new DeathException();
						}
					}
				}
				
				enemyProjectiles.notifyAll();
			}
			Hero.getHero().notifyAll();
		}		
	}
	
}
